package com.xu.crawler.collector;

import com.xu.crawler.config.timeWaitingStrategy.TimeWaitingStrategy;
import com.xu.crawler.enums.URLMapperEnum;
import com.xu.crawler.remote.AbstractRemoteService;
import com.xu.crawler.remote.RemoteCollector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.function.Supplier;

/**
 * Created by clear on 2018/7/10.
 */
public abstract class AbstractCollector<T> extends AbstractRemoteService implements
        Supplier<T>,
        RemoteCollector<T> {

    public Logger log = LoggerFactory.getLogger(AbstractCollector.class);

    /**
     * 收集器收集逻辑,由子类实现
     */
    protected abstract T collectLogic() throws Exception;

    public AbstractCollector(TimeWaitingStrategy strategy) throws RemoteException {
        this(strategy, URLMapperEnum.MAIN_PAGE.toString());
    }

    public AbstractCollector(TimeWaitingStrategy strategy, String webSite) throws RemoteException {
        super(strategy, webSite);
    }

    @Override
    public T get() {
        T res = null;
        int retryTime = this.strategy.retryTimes();
        try {
            int loopTime = 1;
            while (retryTime > loopTime) {
                try {
                    res = collectLogic();
                    break;
                } catch (Exception e) {
                    log.error("Collector: Network busy Retrying -> {} times", loopTime);
                    if (!(e instanceof IOException)) throw e;
                    this.strategy.waiting(loopTime++);
                }
            }
        } catch (Exception e) {
            log.error("{} collecting fail {}", getClass().getSimpleName(), e);
        }
        return res;
    }
}
